//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
// Include lesser types.
#include "Sse2.hpp"


#if defined( _WINDOWS ) || (defined( __APPLE__ ) && (defined( __SSSE3__ ) || defined( __SSE3__ )))
namespace Math
{
	namespace Simd
	{
		//////////////////////////////////////////////////////////////////////////
		// Sse base implementation.
		struct Sse3 : public Sse2
		{
			// SSE3 doesn't actually speed things up in the case of Dot3 and
			// related.  Dot4 and related will be a bit faster.
			// Unfortunately I was using an older set of timings for SSE1 instead
			// of updated timings for SSE3 capable CPU's.
			/*
			static float							Dot3( F32x4_t lhs, F32x4_t rhs )
			{
				F32x4_t		result	=	_mm_mul_ps( lhs, rhs );
				F32x4_t		addHl	=	_mm_hadd_ps( result, result );
				F32x4_t		addLh	=	_mm_hadd_ps( addHl, addHl );
				
				float		sresult;
				_mm_store_ss( &sresult, addLh );
				return sresult;
			}

			static float							Mag3( F32x4_t lhs )
			{
				__m128	result		=	_mm_mul_ps( lhs, lhs );
				result				=	_mm_hadd_ps( result, result );
				result				=	_mm_hadd_ps( result, result );
				result				=	_mm_sqrt_ss( result );

				float				sresult;
				_mm_store_ss( &sresult, result );
				return sresult;
			}

			static F32x4_t							Norm3( F32x4_t lhs )
			{
				__m128	result		=	_mm_mul_ps( lhs, lhs );
				result				=	_mm_hadd_ps( result, result );
				result				=	_mm_hadd_ps( result, result );
				result				=	_mm_sqrt_ss( result );

				static const int	splat	=	_MM_SHUFFLE( 0, 0, 0, 0 );
				result				=	_mm_shuffle_ps( result, result, splat );
				result				=	_mm_div_ps( lhs, result );

				return result;
			}
			*/
		};
	}
}
#endif
